namespace CRM_Perf_BenchMark
{
    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.WebTesting;
    using System.Net;
    using System.Text;
    using System.Xml;    

    /// <summary>
    /// 1. Start point Sales Tab
    /// 2. Click on Accounts
    /// 3. Search for Accounts
    /// 4. Highlight 5 Accounts 
    /// 5. Click Assign Button
    /// 6. Select Assign to another user
    /// 7. Select a User
    /// 8. Click Ok
    /// 9. Save and Close
    /// </summary>

    public class AssignAccounts : CrmWebTest
    {
        public void AssignAccounts_PreWebTest(object sender, PreWebTestEventArgs e)
        {
            EntityRequest er = new EntityRequest();
            er.Type = EntityNames.Users;
            er.ReturnAs = EntityNames.Users;
            er.ParentID = EntityManager.Instance.OrgId;

            System.Collections.Hashtable Props = new System.Collections.Hashtable();

            if (e.WebTest.Context.ContainsKey("UserRole"))
            {
                Props.Add("role", e.WebTest.Context["UserRole"]);
            }            

            EntityRequest AccountEr1 = new EntityRequest();
            AccountEr1.Type = EntityNames.Accounts;
            AccountEr1.ParentID = Guid.NewGuid();
            AccountEr1.ReturnAs = "Account1";

            EntityRequest AccountEr2 = new EntityRequest();
            AccountEr2.Type = EntityNames.Accounts;
            AccountEr2.ParentID = Guid.NewGuid();
            AccountEr2.ReturnAs = "Account2";

            EntityRequest AccountEr3 = new EntityRequest();
            AccountEr3.Type = EntityNames.Accounts;
            AccountEr3.ParentID = Guid.NewGuid();
            AccountEr3.ReturnAs = "Account3";

            EntityRequest AccountEr4 = new EntityRequest();
            AccountEr4.Type = EntityNames.Accounts;
            AccountEr4.ParentID = Guid.NewGuid();
            AccountEr4.ReturnAs = "Account4";

            EntityRequest AccountEr5 = new EntityRequest();
            AccountEr5.Type = EntityNames.Accounts;
            AccountEr5.ParentID = Guid.NewGuid();
            AccountEr5.ReturnAs = "Account5";

            Props.Add("FOO", new EntityRequest[] { AccountEr1, AccountEr2, AccountEr3, AccountEr4, AccountEr5 });
            
            er.Props = Props;

            System.Collections.Hashtable Entities = EntityManager.Instance.GetEntities(er);

            user = (CRMEntity)Entities[EntityNames.Users];
            account[0] = (CRMEntity)Entities["Account1"];
            account[1] = (CRMEntity)Entities["Account2"];
            account[2] = (CRMEntity)Entities["Account3"];
            account[3] = (CRMEntity)Entities["Account4"];
            account[4] = (CRMEntity)Entities["Account5"];

            crmServer = user["CrmServer"];
            tokenKey = EntityManager.Instance.ReadTokenKey(user["organizationid"]);

            e.WebTest.UserName = user["domainName"];
            e.WebTest.Password = user["userpassword"];
            
            user2 = EntityManager.Instance.GetNextUser(new Guid(user["organizationid"]));            
        }

        public void AssignAccounts_PostWebTest(object sender, PostWebTestEventArgs e)
        {
            try
            {
                for(int i = 0; i < 5; i++)
                {
                    if (success)
                    {
                        string newAcctId = account[i][EntityIDNames.Account];
                        if (newAcctId != null)
                        {
                            Guid g = EntityManager.Instance.GetOwnerGuid(new Guid(user2[EntityIDNames.User]), new Guid(user2["OrganizationId"]));
                            EntityManager.Instance.AddEntity(EntityNames.Accounts, g, new string[] { "OwningUser", "AccountID", "name", "EntityManagerOwningUser" }, new string[] { user2["systemuserid"], account[i][EntityIDNames.Account], account[i]["name"], g.ToString() });
                        }
                    }
                }
            }
            finally
            {
                EntityManager.Instance.FreeEntity(user);
                EntityManager.Instance.DeleteEntity(account[0]);
                EntityManager.Instance.DeleteEntity(account[1]);
                EntityManager.Instance.DeleteEntity(account[2]);
                EntityManager.Instance.DeleteEntity(account[3]);
                EntityManager.Instance.DeleteEntity(account[4]);
                EntityManager.Instance.FreeEntity(user2);               
            }            
        }

        private void AssignAccounts_ValidateResponse(object sender, ValidationEventArgs e)
        {
            if (e.Response.StatusCode == HttpStatusCode.OK)
            {
                e.IsValid = true;
                if(success)
                    success = true;
            }
            else
            {
                e.IsValid = false;
                success = false;
            }
        }

        public AssignAccounts()
        {
            WebRequest.RegisterPrefix("crm", new crmRequestFactory());
            string random = Utils.GetRandomString(2, 2);
            gridXml = GridXmlHelper.AccountSearchView(-1, searchAccountView, random, null);
            gridRefreshXml = GridXmlHelper.AccountPageSearchViewRefresh(-1, searchAccountView, random, null);

            this.Proxy = null;            
            PreWebTest += new EventHandler<PreWebTestEventArgs>(AssignAccounts_PreWebTest);
            PostWebTest += new EventHandler<PostWebTestEventArgs>(AssignAccounts_PostWebTest);
        }

        public override IEnumerator<WebTestRequest> GetRequestEnumerator()
        {
            this.BeginTransaction("NavAccountHomepage");

            // Get the home page
            _root_homepage_aspx hp = new _root_homepage_aspx(user);
            hp.etc = 1;
            yield return (hp);

            this.EndTransaction("NavAccountHomepage");

            this.BeginTransaction("SearchAccounts");

            // Search for the Account name
            AppGridWebService.AppGridWebService ag = new AppGridWebService.AppGridWebService();
            WebTestRequest wtr = null;

            try { ag.Reset(gridXml, gridId); }
            catch (crmException x)
            {
                wtr = (CrmRequest)x.wtr;
                wtr.Url = Utils.ReplaceServerName(wtr.Url, user);
            }
            yield return (wtr);

            this.EndTransaction("SearchAccounts");

            this.BeginTransaction("AssignAccounts");

            _grid_cmds_dlg_assign_aspx assign = new _grid_cmds_dlg_assign_aspx(user);
            assign.iObjType = 1;
            assign.iTotal = 5;
            assign.sIds = null;
            yield return (assign);

            _forms_controls_form_css_aspx css = new _forms_controls_form_css_aspx(user);
            css.lcid = 1033;
            yield return (css);

            _common_styles_dialogs_css_aspx styles = new _common_styles_dialogs_css_aspx(user);
            styles.lcid = 1033;
            yield return (styles);
                        
            // Lookup for a user when assigning to other user
            _controls_lookup_lookupsingle_aspx lookup = new _controls_lookup_lookupsingle_aspx(user);
            lookup.Class = "BasicOwner";
            lookup.objecttypes = "8";
            lookup.browse = 0;
            lookup.ShowNewButton = 1;
            lookup.ShowPropButton = 1;
            lookup.DefaultType = 0;
            yield return (lookup);

            _controls_lookup_lookupdialogs_css_aspx clld = new _controls_lookup_lookupdialogs_css_aspx(user);
            clld.lcid = 1033;
            yield return (clld);

            for (int i = 0; i < 5; i++)
            {
                _grid_cmds_dlg_assign_aspx assign2 = new _grid_cmds_dlg_assign_aspx(user);
                assign2.iObjType = 1;
                assign2.iTotal = 1;
                assign2.iIndex = i;
                assign2.ownerId = new Guid(user2[EntityIDNames.User]);
                assign2.ownerType = 8;
                assign2.iId = new Guid(account[i][EntityIDNames.Account]);

                StringHttpBody httpBody = new StringHttpBody();
                httpBody.BodyString = "<node />";
                httpBody.ContentType = "text/xml";
                assign2.Body = httpBody;

                WRPCInfo rpcInfo = Utils.GenerateWRPCToken(_grid_cmds_dlg_assign_aspx.url, user, tokenKey);

                WebTestRequestHeader headerItem = new WebTestRequestHeader();
                headerItem.Name = "CRMWRPCTokenTimeStamp";
                headerItem.Value = rpcInfo.timeStamp.ToString();
                assign2.Headers.Add(headerItem);
                headerItem = new WebTestRequestHeader();
                headerItem.Name = "CRMWRPCToken";
                headerItem.Value = rpcInfo.token;
                assign2.Headers.Add(headerItem);
                assign2.Method = "Post";
                assign2.ValidateResponse += this.AssignAccounts_ValidateResponse;

                yield return (assign2);
            }

            AppGridWebService.AppGridWebService agws = new AppGridWebService.AppGridWebService();
            WebTestRequest wtrRefresh = null;
            try { agws.Refresh(gridRefreshXml); }
            catch (crmException x)
            {
                wtrRefresh = x.wtr;
                wtrRefresh.Url = Utils.ReplaceServerName(wtrRefresh.Url, user);
            }
            yield return (wtrRefresh);
            
            this.EndTransaction("AssignAccounts");
        }

        private string gridXml;
        private string gridRefreshXml;
        private static string gridId = "crmGrid";
        private static string searchAccountView = "2D1187C4-23FE-4BB5-9647-43BB1C6DDBD1";
        private bool success = true;

        private CRMEntity user;
        private CRMEntity user2;
        private CRMEntity[] account = new CRMEntity[5];
        private string crmServer;
        private string tokenKey;
    }
}